package com.its.manager.metadatamanager.serlet;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.ejb.EJBLocalHome;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.sql.DataSource;

public class ServiceLocator {
	//private InitialContext initialContext;
    private Map cache,contextos;
	private static ServiceLocator _instance;
	private static InitialContext context;
	
	/**
	   * Cache where the objects can be stored for later retrieval.
	   * This enhances the performance.
	   */
	 private HashMap serviceCache = null;
	 //metodo estatico que se ejecuta de manera automatica al
	 //cargar la clase, encapsula el singleton
	 static {
		 try {
			 	_instance = new ServiceLocator();
			 	context = new InitialContext();
		 } catch (Exception se) {
			 System.err.println(se);
			 se.printStackTrace(System.err);
		 }
	 }
	
	 private ServiceLocator(){
			 		contextos = Collections.synchronizedMap(new HashMap());			 		
			 		cache = Collections.synchronizedMap(new HashMap());		 
	 }
	
	 static public ServiceLocator getInstance() {
		 return _instance;
	 }
		
	
	
	 /*
	  * <p>Obtiene un Home Local de acuerdo a su JNDI</p>
	  * 
	  */
	 public EJBLocalHome getLocalHome(String jndiHomeName, InitialContext context){
	 	
		 	EJBLocalHome localHome = null;
		 		try {
		 				if (cache.containsKey(jndiHomeName)) {
		 					localHome = (EJBLocalHome)cache.get(jndiHomeName);
		 				} else {
		 					localHome = (EJBLocalHome)
		 					context.lookup(jndiHomeName);
		 					cache.put(jndiHomeName, localHome);
		 				}
		 		} catch (NamingException nex) {
		 			nex.printStackTrace();
		 		} catch (Exception ex) {
		 			ex.printStackTrace();
		 		}
	 return localHome;
	 }
	
	 /*
	  * <p>Obtiene un Home remoto de acuerdo a su JNDI</p>
	  * 
	  */
	 public Object getRemoteHome(
			 	String jndiHomeName, Class homeClassName, InitialContext context){
	 			
		 Object remoteHome = null;
		 try {
			 	if (cache.containsKey(jndiHomeName)) {
			 		remoteHome = cache.get(jndiHomeName);
			 	} else {
			 			Object objref = context.lookup(jndiHomeName);
			 			Object obj = PortableRemoteObject.narrow(objref, homeClassName);
			 			remoteHome = obj;
			 			cache.put(jndiHomeName, remoteHome);
			 	}
	 } catch (NamingException nex) {
		 nex.printStackTrace();
	 } catch (Exception ex) {
		 ex.printStackTrace();
	 }
	 	return remoteHome;
	 }
	 /*
	  * 
	  * 
	  */
	 public DataSource getDataSource(String dataSourceName, InitialContext context){
	  
	  DataSource dataSource = null;
	  	try {
	  		if (cache.containsKey(dataSourceName)) {
	  			dataSource =(DataSource) cache.get(dataSourceName);
	  		} else {
	  			dataSource = (DataSource)
	  			context.lookup(dataSourceName);
	  			cache.put(dataSourceName, dataSource );
	  		}
	  } catch (NamingException nex) {
		  nex.printStackTrace();
	  } catch (Exception ex) {
		  ex.printStackTrace();
	  }
	  return dataSource;
	 }
	 
	 public InitialContext getContexto(String IP){
		 InitialContext context = null;
		 if (cache.containsKey(IP)) {
				context = (InitialContext)cache.get(IP);
			} else {
				
				Properties p = new Properties();
				  p.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
				  p.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
				  p.put("java.naming.provider.url", IP);
				  				  
				  try{
					  context = new InitialContext(p);
				  }catch(NamingException e){
					  e.printStackTrace();
				  }
				  cache.put(IP,context);
			}
			
		 return context;
		 
	 }
	 /**
	  * 
	  * 
	  * @param jndiName
	  * @param context
	  * @return
	  * @throws NamingException
	  */
	 public Object getService(String jndiName) throws NamingException {
		   if (cache.containsKey(jndiName)) {
		 		return cache.get(jndiName);
		 	} else {		 			
		 			cache.put(jndiName, context.lookup(jndiName));
		 	}		 
		    return cache.get(jndiName);
	 }
	
}
	
	

